<template>
  <Component
    ref="refComponent"
    v-bind="{
      ...attrs,
      ...pickOwnForBasicComponent(mappingProps, Component.props, attrs),
    }"
    :class="{
      'no-outline': true,
      'tr-button-group': true,
      'tr-button-group-auto': mappingProps.autoModel,
    }"
    v-show="mappingProps.visible"
    :style="mappingProps.btnSpace ? `gap:${mappingProps.btnSpace}` : ''"
    tabindex="-1"
  >
    <template v-slot:default>
      <template
        v-if="mappingProps.staticItems && mappingProps.staticItems.length > 0"
      >
        <resizeObserver @resize="checkResizeBtn" debounce="100" />
        <Button
          ref="refButton"
          v-for="(item, index) in buttonItems"
          :class="
            item.type
              ? `tr-button-group-item-${item.type}`
              : 'tr-button-group-item-default'
          "
          :icon="item.icon"
          :visible="item.visible"
          :disable="item.disabled"
          :key="'btn-group-btn-' + index"
          :label="item.showIcon ? '' : item.label"
          @click="onClickHandler(item)"
          :showHint="item.hint ? true : false"
          :hintMsg="item.hint"
          :tabIndex="attrs.tabIndex == undefined ? 1 : attrs.tabIndex"
        />
        <ButtonDrop
          ref="refButtonDrop"
          :tabIndex="attrs.tabIndex == undefined ? 1 : attrs.tabIndex"
          :class="{
            'tr-button-group-text': mappingProps.hideBorder,
            'tr-button-group-item-text': mappingProps.hideBorder,
            'tr-button-group-item-default': !mappingProps.hideBorder,
            'tr-buttondrop-notext': mappingProps.btnDropPop,
          }"
          :visible="
            !buttonItemsDrop.every(item => item.visible === false) &&
            mappingProps.moreConf
          "
          :hide-label="true"
          :label="
            !mappingProps.btnDropPop
              ? mappingProps.moreBtnLable ||
                ($q.lang.button?.more ? $q.lang.button.more : '更多')
              : ''
          "
          :staticItems="buttonItemsDrop"
          @dropdownItemClick="onItemClick"
          :dropdown-icon="mappingProps.moreBtnIcon"
          :showModel="mappingProps.moreBtnWidthFixed ? 'fixed' : 'auto'"
          :maxWidth="mappingProps.moreBtnWidthMax"
          :fixedWidth="mappingProps.moreBtnWidth"
          :dropdownWidth="mappingProps.moreBtnWidthFixed ? 'fixed' : 'auto'"
          :no-icon-animation="mappingProps.noIconAnimation"
          :needWatchStaticItems="true"
        />
      </template>
      <slot v-else name="default"></slot>
    </template>
  </Component>
</template>
<script>
import Component from '@teld/q-components/ButtonGroup';
import useMappingProps from 't/common/hooks/useMappingProps';
import {
  commonProps,
  fixNameSpace,
  pickOwnForBasicComponent,
} from 't/common/utils';
import { defineComponent, nextTick, onMounted, ref, toRaw, watch } from 'vue';
import Button from '../button';
import ButtonDrop from '../button-dropdown';
import resizeObserver from '../resize-observer';
import styles from './index.module.scss';
import './index.scss';
import { cloneDeep } from 'lodash';

export default defineComponent({
  name: fixNameSpace(Component.name),
  props: {
    ...commonProps,
    ...Component.props,
    ...ButtonDrop.props,
    staticItems: {
      type: Array,
      default() {
        return [];
      },
    },
    btnSpace: {
      type: String,
      default() {
        return '';
      },
    },
    outline: {
      type: Boolean,
      default() {
        return true;
      },
    },
    square: {
      type: Boolean,
      default() {
        return true;
      },
    },
    moreConf: {
      type: Boolean,
      default() {
        return false;
      },
    },
    autoModel: {
      type: Boolean,
      default() {
        return false;
      },
    },
    moreMaxCount: {
      type: [Number, String],
      default() {
        return 5;
      },
    },
    moreBtnIcon: {
      type: String,
      default() {
        return '';
      },
    },
    moreBtnWidthFixed: {
      type: Boolean,
      default() {
        return false;
      },
    },
    moreBtnWidthMax: {
      type: String,
      default() {
        return '';
      },
    },
    moreBtnWidth: {
      type: String,
      default() {
        return '';
      },
    },
    btnDropPop: {
      type: Boolean,
      default() {
        return false;
      },
    },
    hideBorder: {
      type: Boolean,
      default() {
        return true;
      },
    },
    needWatchStaticItems: {
      type: Boolean,
      default() {
        return false;
      },
    },
    moreBtnLable: {
      type: String,
      default() {
        return '';
      },
    },
    containerGap: {
      type: Number,
      default() {
        return 0;
      },
    },
  },
  emits: ['btn-group-item-click'],
  components: { Component, Button, ButtonDrop, resizeObserver },
  setup(props, { attrs, emit, expose, slots }) {
    const refComponent = ref();
    const refButton = ref();
    const refButtonDrop = ref();
    const buttonItems = ref([]);
    const buttonItemsDrop = ref([]);
    const initButtonWidth = ref([]);
    const staticItems = ref([]);
    const inDesign = ref(!!window['fas']?.inDesign); //判断是否设计时
    let timer = ref(null);
    let timer2 = ref(null);
    const [mappingProps, mappingExpose] = useMappingProps(props, {
      setBtnLoadStateByIndex(index, value) {
        refButton.value[index].loading = value;
      },
      setDisableByIndex(index, value) {
        staticItems.value[index].disabled = value;
        initData();
      },
      setVisibleByIndex(index, value) {
        staticItems.value[index].visible = value;
        initData(true);
      },
      setDisableByCode(code, value) {
        const index = staticItems.value.findIndex(item => item.code == code);
        if (index > -1) {
          staticItems.value[index].disabled = value;
          initData();
        }
      },
      setVisibleByCode(code, value) {
        const index = staticItems.value.findIndex(item => item.code == code);
        if (index > -1) {
          staticItems.value[index].visible = value;
          initData(true);
        }
      },
      setBtnData(data) {
        staticItems.value = [...data];
        i18nMethod();
        initData();
      },
      resizeBtn(width) {
        checkResizeBtn(width);
      },
    });
    if (typeof mappingProps.moreMaxCount != Number) {
      mappingProps.moreMaxCount = parseInt(mappingProps.moreMaxCount);
    }
    let initItems = cloneDeep(mappingProps.staticItems);
    staticItems.value = [...mappingProps.staticItems];
    initData(false, true);
    //国际化处理
    const i18nMethod = () => {
      staticItems.value.forEach((element, index) => {
        let initLabel = initItems[index].label;
        element.codeForClick = initLabel;
      });
      if (!window.Funcs) {
        return;
      }
      for (let i of staticItems.value) {
        if (i.hasOwnProperty('ValueInfo_label')) {
          i.label = Funcs.GetTerms(i.ValueInfo_label, i.label);
        }
        if (i.hasOwnProperty('ValueInfo_hint')) {
          i.hint = Funcs.GetTerms(i.ValueInfo_hint, i.hint);
        }
      }
    };
    expose(mappingExpose);
    i18nMethod();
    console.log('btngroup');
    watch(
      () => {
        return [
          mappingProps.moreConf,
          mappingProps.moreMaxCount,
          mappingProps.autoModel,
        ];
      },
      (newVal, oldVal) => {
        if (!mappingProps.needWatchStaticItems) {
          initData();
        }
      },
    );
    watch(
      () => {
        return mappingProps.staticItems;
      },
      (newVal, oldVal) => {
        let n1 = cloneDeep(newVal);
        let o1 = cloneDeep(oldVal);
        n1.forEach(item => {
          if (item._CmdColumnCmd_) {
            item._CmdColumnCmd_ = '';
          }
          if (item.codeForClick) {
            delete item.codeForClick;
          }
        });
        o1.forEach(item => {
          if (item._CmdColumnCmd_) {
            item._CmdColumnCmd_ = '';
          }
          if (item.codeForClick) {
            delete item.codeForClick;
          }
        });
        if (
          (inDesign.value || mappingProps.needWatchStaticItems) &&
          JSON.stringify(n1) != JSON.stringify(o1)
        ) {
          staticItems.value = [...mappingProps.staticItems];
          initItems = cloneDeep(mappingProps.staticItems);
          i18nMethod();
          initData();
        }
      },
    );

    onMounted(() => {
      // initData();
    });

    function checkResizeBtn(w, ext) {
      // btnWidthCal();
      if (mappingProps.autoModel || ext) {
        onResize({
          width: w ?? refComponent.value?.$el.parentElement?.clientWidth,
        });
      }
    }
    function btnWidthCal() {
      initButtonWidth.value = [];
      if (refButton.value) {
        refButton.value.forEach(button => {
          initButtonWidth.value.push(button.width());
        });
      }
    }
    function onClickHandler(params) {
      if (params.disabled) {
        return;
      }
      let postData = cloneDeep(params);
      postData.codeInit = postData.code;
      postData.code = postData.codeForClick;
      emit('btn-group-item-click', toRaw(postData));
    }

    function onItemClick(params) {
      if (params.disabled) {
        return;
      }
      let postData = cloneDeep(params);
      postData.codeInit = postData.code;
      postData.code = postData.codeForClick;
      emit('btn-group-item-click', toRaw(postData));
    }
    function initData(ext, init) {
      // if (mappingProps.moreConf && !mappingProps.autoModel) {
      buttonItems.value = staticItems.value;
      buttonItemsDrop.value = [];
      if (init) {
        nextTick(() => {
          // if (!ext) {
            btnWidthCal();
          // }
          if (mappingProps.moreConf && !mappingProps.autoModel) {
            buttonItems.value = staticItems.value.slice(
              0,
              mappingProps.moreMaxCount,
            );
            buttonItemsDrop.value = staticItems.value.slice(
              mappingProps.moreMaxCount,
              staticItems.value.length,
            );
          }
          nextTick(() => {
            checkResizeBtn(null, ext);
            clearTimeout(timer2.value);
            timer2.value = null;
          });
        });
      } else {
        timer.value = setTimeout(() => {
          // nextTick(() => {
          // if (!ext) {
            btnWidthCal();
          // }
          if (mappingProps.moreConf && !mappingProps.autoModel) {
            buttonItems.value = staticItems.value.slice(
              0,
              mappingProps.moreMaxCount,
            );
            buttonItemsDrop.value = staticItems.value.slice(
              mappingProps.moreMaxCount,
              staticItems.value.length,
            );
          }
          // nextTick(() => {
          timer2.value = setTimeout(() => {
            checkResizeBtn(null, ext);
            clearTimeout(timer2.value);
            timer2.value = null;
          }, 10);
          // });
          // });
          clearTimeout(timer.value);
          timer.value = null;
        }, 10);
      }
    }
    const resizeWidth = ref(0);
    const resizeCount = ref(0);
    function onResize(size) {
      console.log('resize', size);
      if (
        mappingProps.moreConf &&
        mappingProps.autoModel &&
        initButtonWidth.value.length > 0 &&
        size
      ) {
        updateButtonsVisibility(size.width);

        // btnWidthCal();
      }
    }
    function updateButtonsVisibility(container) {
      let containerWidth =
        container -
        (mappingProps.containerGap ? mappingProps.containerGap + 10 : 0);
      let totalButtonWidth = refButtonDrop.value?.width() ?? 0; //下拉按钮的宽度
      let buttonIndex = 0;
      let length = initButtonWidth.value.filter(width => width > 0)?.length; //显示的按钮数量
      //全部隐藏后会失去按钮对象，获取不到宽度，所以一开始用initButtonWidth保存下初始值，并在这里使用
      let arr = [];
      initButtonWidth.value.forEach((buttonWidth, index) => {
        if (buttonWidth != 0) totalButtonWidth += buttonWidth + 8;
        if (totalButtonWidth < containerWidth) {
          if (buttonWidth != 0) {
            arr.push(buttonWidth);
          }
          buttonIndex = arr.length; //长度
        }
      });
      if (buttonIndex < length) {
        let splitIndex = buttonIndex;
        if (splitIndex <= 0) {
          buttonItems.value = [];
          buttonItemsDrop.value = staticItems.value.slice(
            0,
            staticItems.value.length,
          );
        } else {
          if (
            mappingProps.moreMaxCount &&
            buttonIndex >= mappingProps.moreMaxCount
          ) {
            splitIndex = mappingProps.moreMaxCount;
          }
          let listValue = staticItems.value.filter(item => item.visible);
          let newIndex =
            mappingProps.needWatchStaticItems && mappingProps.containerGap > 0
              ? splitIndex
              : mappingProps.needWatchStaticItems ||
                  refButtonDrop.value?.width() === 0
                ? length-splitIndex > 1? splitIndex:splitIndex - 1
                : splitIndex;
          buttonItems.value = listValue.slice(0, newIndex);
          buttonItemsDrop.value = listValue.slice(newIndex, listValue.length);
        }
      } else if (buttonIndex == length && mappingProps.moreMaxCount < length) {
        let listValue = staticItems.value.filter(item => item.visible);
        buttonItems.value = listValue.slice(0, mappingProps.moreMaxCount);
        buttonItemsDrop.value = listValue.slice(
          mappingProps.moreMaxCount,
          listValue.length,
        );
      } else {
        buttonItems.value = staticItems.value;
        buttonItemsDrop.value = [];
      }
    }

    return {
      refComponent,
      refButton,
      refButtonDrop,
      attrs,
      mappingProps,
      Component,
      styles,
      onClickHandler,
      onItemClick,
      pickOwnForBasicComponent,
      buttonItems,
      buttonItemsDrop,
      onResize,
    };
  },
});
</script>
